package service

import (
	"errors"

	"gitee.com/war2001/NiuMaEasyGo/model"
	"gorm.io/gorm"
)

// WechatConfigServiceImpl 微信配置服务实现
type WechatConfigServiceImpl struct {
	db *gorm.DB
}

// NewWechatConfigService 创建微信配置服务
func NewWechatConfigService(db *gorm.DB) model.WechatConfigService {
	return &WechatConfigServiceImpl{db: db}
}

// Create 创建微信配置
func (s *WechatConfigServiceImpl) Create(config *model.WechatConfig) error {
	// 检查是否设置为默认
	if config.IsDefault {
		// 如果设置为默认，需要将同一商户同类型的其他配置设置为非默认
		if err := s.db.Model(&model.WechatConfig{}).
			Where("tenant_id = ? AND type = ? AND is_default = ?",
				config.TenantID, config.Type, true).
			Update("is_default", false).Error; err != nil {
			return err
		}
	}

	return s.db.Create(config).Error
}

// Update 更新微信配置
func (s *WechatConfigServiceImpl) Update(config *model.WechatConfig) error {
	// 检查是否存在
	var count int64
	if err := s.db.Model(&model.WechatConfig{}).Where("id = ?", config.ID).Count(&count).Error; err != nil {
		return err
	}
	if count == 0 {
		return errors.New("微信配置不存在")
	}

	// 检查是否设置为默认
	if config.IsDefault {
		// 如果设置为默认，需要将同一商户同类型的其他配置设置为非默认
		if err := s.db.Model(&model.WechatConfig{}).
			Where("tenant_id = ? AND type = ? AND is_default = ? AND id != ?",
				config.TenantID, config.Type, true, config.ID).
			Update("is_default", false).Error; err != nil {
			return err
		}
	}

	return s.db.Save(config).Error
}

// Delete 删除微信配置
func (s *WechatConfigServiceImpl) Delete(id uint) error {
	// 检查是否为默认配置
	var config model.WechatConfig
	if err := s.db.Where("id = ?", id).First(&config).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("微信配置不存在")
		}
		return err
	}

	// 如果是默认配置，不允许删除
	if config.IsDefault {
		return errors.New("默认配置不能删除，请先设置其他配置为默认")
	}

	return s.db.Delete(&model.WechatConfig{}, id).Error
}

// GetByID 根据ID获取微信配置
func (s *WechatConfigServiceImpl) GetByID(id uint) (*model.WechatConfig, error) {
	var config model.WechatConfig
	if err := s.db.Where("id = ?", id).First(&config).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("微信配置不存在")
		}
		return nil, err
	}
	return &config, nil
}

// GetByTenantAndType 根据商户ID和类型获取微信配置
func (s *WechatConfigServiceImpl) GetByTenantAndType(tenantID uint, configType string) (*model.WechatConfig, error) {
	var config model.WechatConfig
	if err := s.db.Where("tenant_id = ? AND type = ?", tenantID, configType).First(&config).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("微信配置不存在")
		}
		return nil, err
	}
	return &config, nil
}

// GetDefault 获取默认微信配置
func (s *WechatConfigServiceImpl) GetDefault(tenantID uint, configType string) (*model.WechatConfig, error) {
	var config model.WechatConfig
	if err := s.db.Where("tenant_id = ? AND type = ? AND is_default = ?",
		tenantID, configType, true).First(&config).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("默认微信配置不存在")
		}
		return nil, err
	}
	return &config, nil
}

// ListByTenant 获取商户的所有微信配置
func (s *WechatConfigServiceImpl) ListByTenant(tenantID uint) ([]*model.WechatConfig, error) {
	var configs []*model.WechatConfig
	if err := s.db.Where("tenant_id = ?", tenantID).Find(&configs).Error; err != nil {
		return nil, err
	}
	return configs, nil
}

// SetDefault 设置默认微信配置
func (s *WechatConfigServiceImpl) SetDefault(id uint, tenantID uint) error {
	// 获取要设置为默认的配置
	var config model.WechatConfig
	if err := s.db.Where("id = ? AND tenant_id = ?", id, tenantID).First(&config).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("微信配置不存在或不属于该商户")
		}
		return err
	}

	// 开启事务
	return s.db.Transaction(func(tx *gorm.DB) error {
		// 将同类型的其他配置设置为非默认
		if err := tx.Model(&model.WechatConfig{}).
			Where("tenant_id = ? AND type = ? AND is_default = ? AND id != ?",
				tenantID, config.Type, true, id).
			Update("is_default", false).Error; err != nil {
			return err
		}

		// 将当前配置设置为默认
		if err := tx.Model(&model.WechatConfig{}).
			Where("id = ?", id).
			Update("is_default", true).Error; err != nil {
			return err
		}

		return nil
	})
}
